home *** CD-ROM | disk | FTP | other *** search
/ Linux Cubed Series 3: Developer Tools / Linux Cubed Series 3 - Developer Tools.iso / devel / lang / lisp / stk-3.002 / stk-3 / STk-3.1 / Src / argv.c < prev    next >
Encoding:
C/C++ Source or Header  |  1996-07-23  |  7.9 KB  |  316 lines

  1. /*
  2.  *
  3.  * a r g v . c            -- Argc/Argv management
  4.  *
  5.  * Copyright ⌐ 1993-1996 Erick Gallesio - I3S-CNRS/ESSI <eg@unice.fr>
  6.  * 
  7.  *
  8.  * Permission to use, copy, and/or distribute this software and its
  9.  * documentation for any purpose and without fee is hereby granted, provided
  10.  * that both the above copyright notice and this permission notice appear in
  11.  * all copies and derived works.  Fees for distribution or use of this
  12.  * software or derived works may only be charged with express written
  13.  * permission of the copyright holder.  
  14.  * This software is provided ``as is'' without express or implied warranty.
  15.  *
  16.  * This software is a derivative work of other copyrighted softwares; the
  17.  * copyright notices of these softwares are placed in the file COPYRIGHTS
  18.  *
  19.  *
  20.  *           Author: Erick Gallesio [eg@kaolin.unice.fr]
  21.  *    Creation date: 30-Aug-1994 15:38
  22.  * Last file update: 23-Jul-1996 16:00
  23.  */
  24.  
  25. #include "stk.h"
  26.  
  27. #ifdef WIN32
  28. #include <process.h>
  29. #include <io.h>
  30. #include <stdlib.h>
  31. #endif
  32.  
  33. /* Previous versions of Stk use the TkArgv mechanism for managing argc/argv.
  34.  * Here is an ad hoc version for argc/argv hich is simpler than the original
  35.  * one and which can be used when NO_TK is defined
  36.  */
  37.  
  38. #ifdef USE_TK
  39. char *STk_arg_Xdisplay       = NULL;
  40. char *STk_arg_geometry       = NULL;
  41. char *STk_arg_name       = NULL;
  42. char *STk_arg_visual      = NULL;
  43. int   STk_arg_colormap      = 0;
  44. int   STk_arg_sync      = 0;
  45. int   STk_arg_no_tk      = 0;
  46. #endif
  47. char *STk_arg_file      = NULL;
  48. char *STk_arg_load      = NULL;
  49. char *STk_arg_image      = NULL;
  50. char *STk_arg_cells      = NULL;
  51. int   STk_arg_interactive = 0;
  52.  
  53. static struct arguments {
  54.   char *key;
  55.   char **flag;
  56.   char need_argument;
  57.   char *init;
  58.   char *help;
  59. } Table[] = {
  60. #ifdef USE_TK
  61.   {"-geometry",       &STk_arg_geometry,           1, NULL,
  62.            "Initial geometry for window"},
  63.   {"-display",       &STk_arg_Xdisplay,           1, NULL,
  64.            "Display to use"},
  65.   {"-new-colormap",&STk_arg_colormap,           0, (char *) 0,
  66.               "Use a private colormap"},
  67.   {"-name",       &STk_arg_name,           1, NULL,
  68.            "\tName to use for application"},
  69.   {"-sync",       (char **) &STk_arg_sync,       0, (char *) 0,
  70.            "\tUse synchronous mode for display server"},
  71.   {"-visual",        &STk_arg_visual,           1, NULL,
  72.               "Visual for main window"},
  73.   {"-no-tk",       (char **) &STk_arg_no_tk,       0, (char *) 0,
  74.            "\tDon't initialize Tk"},
  75. #endif
  76.   {"-file",       &STk_arg_file,           1,  NULL,
  77.            "\tFile from which to read commands"},
  78.   {"-load",       &STk_arg_load,           1,  NULL,
  79.            "\tFile to load after all the initializations are done"},
  80.   {"-cells",       &STk_arg_cells,           1, (char *) 0L,
  81.            "\tDefault size for heap"},
  82.   {"-image",       &STk_arg_image,           1,  NULL,
  83.            "\tUse  previously created image"},
  84.   {"-interactive", (char **) &STk_arg_interactive, 0, (char *) 0,
  85.            "Interactive mode"},
  86.   {"-help",       NULL,               0,  NULL,
  87.            "\tPrint summary of command-line options and abort"},
  88.   {"", NULL, 0, NULL, ""}};
  89.  
  90. static void usage(void)
  91. {
  92.   struct arguments *p;
  93.   
  94.   for (p = Table; *(p->key); p++) 
  95.     fprintf(STk_stderr, "%s\t%s\n", p->key, p->help);
  96.   exit(1);
  97. }
  98.  
  99. char **STk_process_argc_argv(int argc, char **argv)
  100. {
  101.   struct arguments *p;
  102.   char **new_argv;
  103.   int i;
  104.   
  105.   /* Reset arguments to their default value */
  106.   for (p = Table; *(p->key); p++) 
  107.     if (p->flag)
  108.       *(p->flag) = p->init;
  109.  
  110.   /* Set the program name */
  111.   STk_whence(*argv, STk_Argv0);
  112.  
  113.   /* Option analysis */
  114.   while (--argc) {
  115.     char *arg  = *++argv;
  116.     int found  = FALSE;
  117.  
  118.     if (!*arg) break;
  119.     
  120.     if (strcmp(arg, "--") == 0) { /* Special delimiter */
  121.       argv += 1;
  122.       argc -= 1;
  123.       break;
  124.     }
  125.     /* Try to find the option in table */
  126.     for (p = Table; *(p->key); p++) {
  127.       if (strlen(arg) >= 2) {
  128.     if  (strstr(p->key, arg)== p->key) {
  129.       found = TRUE;
  130.     
  131.       if (p->need_argument) {
  132.         argc -= 1;
  133.         argv += 1;
  134.         
  135.         if (*argv) 
  136.           *(p->flag) = *argv;
  137.         else {
  138.           fprintf(STk_stderr,
  139.               "\"%s\"  option requires an additional argument\n", 
  140.               p->key);
  141.           exit(1);
  142.         }
  143.       }
  144.       else
  145.         if (p->flag)
  146.           *(p->flag) = (char *) TRUE;
  147.         else
  148.            usage();
  149.     }
  150.       }
  151.     }
  152.     
  153.     if (!found) break;
  154.   }
  155.   
  156.   /* Option have been analysed. Parse program arguments */
  157.   new_argv = (char**) must_malloc((argc + 1)  * sizeof(char*));
  158.  
  159.   for (i = 0; argc; argc--) {
  160.     new_argv[i++] = *argv++;
  161.   }
  162.   new_argv[i] = NULL;
  163.   return new_argv;
  164. }
  165.  
  166. /******************************************************************************
  167.  *
  168.  * Unix environment saving
  169.  *
  170.  *     The two following function permit to save/restore the argc/argv/envp
  171.  * in a file. They are used upon image restauration.
  172.  *
  173.  ******************************************************************************/
  174. void STk_save_unix_args_and_environment(int argc, char **argv)
  175. {
  176.   FILE *f;
  177.   char **env;
  178.   char filename[50];
  179.   extern char **environ;
  180.  
  181.   /* Open a file in which we will save argc/argv/envp */
  182.   sprintf(filename, "/usr/tmp/STktmp%d", getpid());
  183.   if ((f = fopen(filename, "w")) == NULL) {
  184.     STk_panic("Cannot save environment in %s.\n ABORT.\n", filename);
  185.     exit(1);
  186.   }
  187.  
  188.   /* print argc */
  189.   fprintf(f, "%d\n", argc);
  190.  
  191.   /* print argv */
  192.   for ( ; argc; argc-=1, argv+=1) {
  193.     fprintf(f, "%d %s\n", strlen(*argv), *argv);
  194.   }
  195.  
  196.   /* print environment */
  197.   for (env=environ; *env; env++) {};
  198.   fprintf(f, "%d\n", env-environ);
  199.  
  200.   for (env=environ; *env; env++) {
  201.     fprintf(f, "%d %s\n", strlen(*env), *env);
  202.   }
  203.  
  204.   /* Close file */
  205.   fclose(f);
  206. }
  207.  
  208. void STk_restore_unix_args_and_environment(int *argc, char ***argv)
  209. {
  210.   FILE *f;
  211.   int i, l, Argc, env_len;
  212.   char **Argv, **Env;
  213.   char filename[50];
  214.   extern char **environ;
  215.  
  216.   /* Open a file in which we have saved argc/argv/envp */
  217.   sprintf(filename, "/usr/tmp/STktmp%d", getpid());
  218.   if ((f = fopen(filename, "r")) == NULL) {
  219.     STk_panic("Cannot re-open environment in %s.\n ABORT.\n", filename);
  220.     exit(1);
  221.   }
  222.  
  223.   /* Read argc */
  224.   fscanf(f, "%d", &Argc); getc(f);
  225.  
  226.   /* Read argv */
  227.   Argv = must_malloc((Argc+1) * sizeof(char *));
  228.  
  229.   for (i=0; i<Argc; i++) {
  230.     fscanf(f, "%d", &l); getc(f);
  231.     Argv[i] = must_malloc(l+1);
  232.     fread(Argv[i], 1, l, f);
  233.     Argv[i][l] = '\0';
  234.   }
  235.   Argv[Argc] = NULL;
  236.  
  237.   /* Read environment */
  238.   fscanf(f, "%d", &env_len); getc(f);
  239.   Env = must_malloc((env_len+1) * sizeof(char *));
  240.   for (i=0; i<env_len; i++) {
  241.     fscanf(f, "%d", &l); getc(f);
  242.     Env[i] = must_malloc(l+1);
  243.     fread(Env[i], 1, l, f);
  244.     Env[i][l] = '\0';
  245.   }
  246.   Env[i]= NULL;
  247.  
  248.   /* Save read values in global variables */
  249.   *argc   = Argc;
  250.   *argv   = Argv;
  251.   environ = Env;
  252.   
  253.   /* close & delete temporary file */
  254.   fclose(f);
  255.   unlink(filename);
  256. }
  257.  
  258.  
  259. void STk_initialize_scheme_args(char **argv)
  260. {
  261.   SCM l;
  262.  
  263.   for (l = NIL; *argv; argv++)
  264.     l = Cons(STk_makestring(*argv), l);
  265.   
  266.   VCELL(Intern(ARGV))      = Reverse(l);
  267.   VCELL(Intern(PROG_NAME)) = STk_makestring(STk_Argv0);
  268. }
  269.  
  270. #ifdef WIN32
  271. #include <dos.h>
  272.  
  273. char **STk_Win32_make_argc_argv(char *lpszCmdLine, int *argc)
  274. {
  275.   int size, i, code;
  276.   char **argv, **argvlist, *p, *tmp, *prog= "STk.exe";
  277.  
  278.   /*
  279.    * First get an upper bound on the size of the argv array by counting the
  280.    * number of whitespace characters in the string.
  281.    */
  282.   for (size=1, p=lpszCmdLine; *p != '\0'; p++) {
  283.     if (isspace(UCHAR(*p))) size++;
  284.   }
  285.   size+=2;        /* Leave space for program name final NULL pointer. */
  286.   argvlist = (char **) ckalloc((unsigned) (size * sizeof(char *)));
  287.   argv = argvlist;
  288.  
  289.   p = getenv("STK_LIBRARY");
  290.   if (p == NULL) 
  291.     panic("You must set the STK_LIBRARY variable");
  292.   tmp = must_malloc(strlen(p) + strlen(prog) + 2);
  293.   sprintf(tmp, "%s/%s", p, prog);
  294.   argv[0] = tmp;            /* FIXME */
  295.  
  296.   /*
  297.    * Split the command line into words, and store pointers to the start of
  298.    * each word into the argv array.  Skips leading whitespace on each word.
  299.    */
  300.  
  301.   for (i=1, p=lpszCmdLine; *p != '\0'; i++) {
  302.     while (isspace(UCHAR(*p))) p++;
  303.     if (*p == '\0') break;
  304.     
  305.     argv[i] = p;
  306.     while (*p != '\0' && !isspace(UCHAR(*p))) 
  307.       p++;
  308.     if (*p) *p++ = '\0';
  309.   }
  310.   argv[i] = NULL;
  311.   *argc = i;
  312.   
  313.   return argv;
  314. }
  315. #endif
  316.